Skip to content

feat(gateway): stream the Anthropic /v1/messages endpoint - #126

Merged
prashar32 merged 2 commits into
mainfrom
feat/anthropic-streaming
Jun 14, 2026
Merged

feat(gateway): stream the Anthropic /v1/messages endpoint#126
prashar32 merged 2 commits into
mainfrom
feat/anthropic-streaming

Conversation

@prashar32

Copy link
Copy Markdown
Owner

Streaming (stream:true) already worked on the OpenAI-compatible
/v1/chat/completions path; this wires it for the Anthropic-compatible
/v1/messages path so both surfaces stream, completing #22.

The Anthropic provider now implements provider.Streamer. Its events are
forwarded to the client verbatim — authentic Anthropic SSE (event: +
data: lines), no translation — while the run is metered from the stream's own
accounting: input_tokens arrives on message_start (along with the model),
the final cumulative output_tokens on message_delta.

The gateway path is unchanged: /v1/messages with stream:true now routes
through the same generic streamCall the OpenAI path uses, so every guarantee
carries over — the budget is enforced before the stream opens, dollar/token
usage is recorded after the stream closes (so the next call is refused if it
went over), and the run's context (time budget / kill switch / client
disconnect) cuts a live stream. A provider whose backend doesn't implement
streaming still returns a clear 501.

Also factored the system-prompt lifting and max-tokens defaulting shared by
Chat and ChatStream into small helpers (splitSystem, anthropicMaxTokens).

Tests

  • Provider: TestAnthropicChatStream — authentic Anthropic SSE in, verbatim
    bytes out, usage assembled (input from message_start, final output from
    message_delta overriding the initial value), model extracted; plus the
    API-error and missing-key paths.
  • Gateway: TestMessagesStreamingProxy_ForwardsAndMeters/v1/messages
    with stream:true forwards the Anthropic SSE verbatim and meters the call
    against the run.
  • go test -race ./... green; go vet ./... clean; gofmt clean.

Wire native SSE streaming for the Anthropic-compatible endpoint, completing
the streaming surface that /v1/chat/completions already had. The provider's
events are forwarded to the client verbatim (authentic Anthropic SSE, no
translation) while the run is metered from the stream's own accounting:
input_tokens from message_start, the final cumulative output_tokens from
message_delta.

Reuses the generic streamCall path, so the same guarantees apply: the budget
is enforced before the stream opens, dollar/token usage is recorded after, and
the run's context (time budget, kill switch, client disconnect) cuts a live
stream. A provider whose backend doesn't implement streaming still returns a
clear 501.

Tests: provider-level SSE parse (verbatim forward + usage/model extraction,
API-error and missing-key paths) and a gateway-level /v1/messages streaming
test asserting verbatim forwarding and per-run metering.
@prashar32
prashar32 merged commit f71c173 into main Jun 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant